﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace MDAControlsFramework.Helpers {
	public class Animation: ICloneable {
		private Image _oldFormImage = null;
		private Image _newFormImage = null;
		private Form _topForm = null;
		private int _speed = 300;
		AnimationTypesEnum _animType = AnimationTypesEnum.none;
		private int _length = 0;
		private int _x = 0, _y = 0;
		private int _width, _height;
		private bool _animate = false;
		private int _lastTick = 0;
		private int _distance = 0;

		public Animation() {
		}

		public Animation(Form form) {
			_topForm = form;
		}

		public object Clone() {
			Animation clone = this.MemberwiseClone() as Animation;
			return clone;
		}

		#region properties

		public Image OldFormImage {
			get {
				return _oldFormImage;
			}
			set {
				_oldFormImage = value;
			}
		}

		public Image NewFormImage {
			get {
				return _newFormImage;
			}
			set {
				_newFormImage = value;
			}
		}

		public Form TopForm {
			get {
				return _topForm;
			}
			set {
				_topForm = value;
			}
		}

		public AnimationTypesEnum AnimType {
			get {
				return _animType;
			}
			set {
				_animType = value;
			}
		}

		public bool Animate {
			get {
				return _animate;
			}
			set {
				_animate = value;
			}
		}

		#endregion

		public void PrepareAnimation(MDAControl control) {
			_oldFormImage = new Bitmap(control.Width, control.Height);
			Graphics g = Graphics.FromImage(_oldFormImage);
			control.Draw(g);
			g.Dispose();
		}

		public void StartAnimate(MDAControl control) {
			_newFormImage = new Bitmap(control.Width, control.Height);
			Graphics g = Graphics.FromImage(_newFormImage);
			control.Draw(g);
			g.Dispose();

			_x = control.X;
			_y = control.Y;
			_width = _newFormImage.Width;
			_height = _newFormImage.Height;
			_animate = true;
			_lastTick = 0;
			switch (_animType) {
				case AnimationTypesEnum.rightToLeft:
				case AnimationTypesEnum.leftToRight:
					_length = _newFormImage.Width;
					break;
				case AnimationTypesEnum.topToBottom:
				case AnimationTypesEnum.bottomToTop:
					_length = _newFormImage.Height;
					break;
				default:
					_length = 0;
					break;
			}
		}

		public void Draw(Graphics graphics) {
			int tickDiff = Environment.TickCount - _lastTick;
			if (_lastTick == 0) {
				tickDiff = 0;
				_distance = 0;
			}

			_lastTick = Environment.TickCount;
			_distance += (tickDiff * _length) / _speed;

			if (_distance < _length) {
				// probiha animace
				switch (_animType) {
					case AnimationTypesEnum.rightToLeft:
						graphics.DrawImage(_oldFormImage, -_distance, _y);
						graphics.DrawImage(_newFormImage, _length - _distance, _y);
						break;

					case AnimationTypesEnum.leftToRight:
						graphics.DrawImage(_oldFormImage, _distance, _y);
						graphics.DrawImage(_newFormImage, _distance - _length, _y);
						break;

					case AnimationTypesEnum.topToBottom:
						graphics.DrawImage(_oldFormImage, _x, -_distance);
						graphics.DrawImage(_newFormImage, _x, _length - _distance);
						break;

					case AnimationTypesEnum.bottomToTop:
						graphics.DrawImage(_oldFormImage, _x, _distance);
						graphics.DrawImage(_newFormImage, _x, _distance - _length);
						break;

					case AnimationTypesEnum.showFromTop:
						if (_oldFormImage != null) {
							graphics.DrawImage(_oldFormImage, _x, _y);
						}
						graphics.DrawImage(_newFormImage, _x, _distance);
						break;

					case AnimationTypesEnum.showFromBottom:
						if (_oldFormImage != null) {
							graphics.DrawImage(_oldFormImage, _x, _y);
						}
						graphics.DrawImage(_newFormImage, _x, -_distance);
						break;

					case AnimationTypesEnum.showFromLeft:
						if (_oldFormImage != null) {
							graphics.DrawImage(_oldFormImage, _x, _y);
						}
						graphics.DrawImage(_newFormImage, _distance, _y);
						break;

					case AnimationTypesEnum.showFromRight:
						if (_oldFormImage != null) {
							graphics.DrawImage(_oldFormImage, _x, _y);
						}
						graphics.DrawImage(_newFormImage, -_distance, _y);
						break;

				}
			} else { // posledni snimek animace
				_animate = false;
				graphics.DrawImage(_newFormImage, _x, _y);
			}

			_topForm.Invalidate();
		}
	}

	public enum AnimationTypesEnum {
		none,
		leftToRight,
		rightToLeft,
		topToBottom,
		bottomToTop,
		showFromTop,
		showFromBottom,
		showFromLeft,
		showFromRight
	}

}
